<template>
  <div class="table_form_wrap">
    <el-card class="sourcing-search-card" shadow="never">
      <el-row slot="header" type="flex" justify="space-between" align="middle">
        <div class="el-icon-search icon">&nbsp;筛选查询</div>
        <el-row>
          <BtnRender :render="actionRender" />
          <slot name="extensionActions" />
        </el-row>
      </el-row>
      <el-row>
        <el-form
          :ref="refName"
          :model="formData"
          :inline="isInline"
          :disabled="allDisabled"
        >
          <el-row v-for="(rowNum, rowIndex) in totalRowNum" :key="rowIndex">
            <el-col
              v-for="(item, index) in formItemList.slice(
                rowIndex * colNumOfRow,
                rowNum * colNumOfRow
              )"
              :key="item.prop + index"
              :span="24 / colNumOfRow"
            >
              <el-form-item
                :prop="item.prop"
                :label="item.label"
                :label-width="item.width || formItemWidth"
              >
                <!-- 普通输入框 -->
                <template v-if="item.type === 'input'">
                  <el-input
                    clearable
                    v-model.trim="formData[item.prop]"
                    :placeholder="item.placeholder || `请输入${item.label}`"
                    :disabled="item.disabled"
                  />
                </template>
                <!-- 普通下拉框 -->
                <template v-else-if="item.type === 'select'">
                  <el-select
                    ref="elSelect"
                    collapse-tags
                    v-model="formData[item.prop]"
                    style="width: 100%"
                    :multiple="item.multiple"
                    :filterable="item.remote || true"
                    :filter-method="item.filterMethod"
                    :placeholder="item.placeholder || `请选择${item.label}`"
                    :disabled="item.disabled"
                    :clearable="item.clearable || true"
                    :remote="item.remote"
                    :remote-method="(val) => { handleRemoteSelect(val, item) }"
                    :reserve-keyword="item.reserveKeyword"
                    :loading="selectRemoteLoading[item.prop]"
                  >
                    <el-option
                      v-for="option in getSelectOptions(item)"
                      :key="getSelectOptionKeys(option, item).key"
                      :label="getSelectOptionKeys(option, item).label"
                      :value="getSelectOptionKeys(option, item).value"
                      :disabled="isOptionDisabled(option, item)"
                    />
                  </el-select>
                </template>
                <!-- 自定义搜索条件下拉框 -->
                <template v-else-if="item.type === 'selectFilter'">
                  <el-select
                    v-model="formData[item.prop]"
                    style="width: 100%"
                    :multiple="item.multiple"
                    :filterable="item.filterable"
                    :filter-method="(query) => handleFilterOptions(query, item)"
                    :placeholder="item.placeholder || `请输入${item.label}`"
                    :disabled="item.disabled"
                    :clearable="item.clearable"
                    collapse-tags
                  >
                    <el-option
                      v-for="item in item.options"
                      :key="item.value"
                      :label="item.label"
                      :value="item.value"
                    />
                  </el-select>
                </template>
                <!-- 日期选择器 -->
                <template v-else-if="item.type === 'datePicker'">
                  <el-date-picker
                    v-model="formData[item.prop]"
                    type="date"
                    style="width: 100%"
                    value-format="yyyy-MM-dd"
                    :disabled="item.disabled"
                    placeholder="选择日期"
                  />
                </template>
                <!-- 日期时间选择器 -->
                <template v-else-if="item.type === 'dateTimePicker'">
                  <el-date-picker
                    v-model="formData[item.prop]"
                    type="datetime"
                    style="width: 100%"
                    value-format="yyyy-MM-dd HH:mm:ss"
                    :disabled="item.disabled"
                    placeholder="选择日期"
                  />
                </template>
                <!-- 日期区间选择器 -->
                <template v-else-if="item.type === 'dateRangePicker'">
                  <el-date-picker
                    v-model="formData[item.prop]"
                    type="daterange"
                    style="width: 100%"
                    value-format="yyyy-MM-dd"
                    :range-separator="item.rangeSeparator || '-'"
                    :start-placeholder="item.startPlaceholder || '开始日期'"
                    :end-placeholder="item.endPlaceholder || '结束日期'"
                    :disabled="item.disabled"
                  />
                </template>
                <!-- 日期时间区间选择器 -->
                <template v-else-if="item.type === 'dateTimeRangePicker'">
                  <el-date-picker
                    v-model="formData[item.prop]"
                    type="datetimerange"
                    style="width: 100%"
                    value-format="yyyy-MM-dd HH:mm:ss"
                    :default-time="['00:00:00', '23:59:59']"
                    :range-separator="item.rangeSeparator || '-'"
                    :start-placeholder="item.startPlaceholder || '开始日期'"
                    :end-placeholder="item.endPlaceholder || '结束日期'"
                    :disabled="item.disabled"
                  />
                </template>
                <!-- 品类选择 -->
              <template v-else-if="item.type === 'category'">
                <CategorySelect ref="categorySelect" @getCategoryUuid="getCategoryUuid"/>
              </template>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </el-row>
    </el-card>
    <SetSearchFields :visible.sync="setFieldsVisible" @submitCallback="setSearchFieldCallback" :menuId="menuId" />
  </div>
</template>
<script>
import { mapGetters } from 'vuex';
import { getBtnsId } from '@/libs/btnsPermission';
import BtnRender from './BtnRender';
import CategorySelect from '@sourcing/components/CategorySelect';
import SetSearchFields from '@sourcing/components/SetSearchFields';

export default {
  props: {
    formColumns: { // 表单item名集合
      type: Array,
      default () {
        return [];
      }
    },
    dataSource: { // 表单formData
      type: Object,
      default () {
        return {};
      }
    },
    formItemWidth: { // 表单item默认宽度
      type: String,
      default: '100px'
    },
    isInline: { // 表单是否开启inline模式
      type: Boolean,
      default: false
    },
    colNumOfRow: { // 表单每行col数量
      type: Number,
      default: 4
    },
    handleSearchForm: { // 查询方法
      type: Function
    },
    handleClearForm: { // 清空方法
      type: Function
    },
    searchBtnRender: { // 查询按钮（外部需要特殊渲染所用）
      type: Function
    },
    resetBtnRender: { // 清空按钮（外部需要特殊渲染所用）
      type: Function
    },
    searchBtnName: { // 查询按钮名称
      type: String,
      default: '查询'
    },
    resetBtnName: { // 清空按钮名称
      type: String,
      default: '重置'
    },
    isResetToQuery: { // 清空表单是否同时调用查询事件
      type: Boolean,
      default: false
    },
    refName: { // 表单ref名
      type: String,
      default: 'formData'
    },
    actionPosition: { // 表单操作按钮栏位置
      type: String,
      default: 'end'
    },
    allDisabled: { // 表单是否开启禁用
      type: Boolean,
      default: false
    },
    isScalingBtn: { // 是否展示收起或展开按钮
      type: Boolean,
      default: true
    },
    defaultExpandStatus: { // true为展开状态，按钮为收起；false为收起状态，按钮为展开
      type: Boolean,
      default: false
    },
    isBtnBarSingleRow: { // 按钮操作栏是否单独一行
      type: Boolean,
      default: false
    },
    hasQueryPermission: { // 是否需要查询按钮添加权限判断，默认添加
      type: Boolean,
      default: true
    },
    // 需要自定义查询条件
    needSetSearchFields: {
      type: Boolean,
      default: false
    },
    // 自定义查询条件菜单id
    menuId: {
      type: Number,
    },
  },
  components: {
    BtnRender,
    CategorySelect,
    SetSearchFields
  },
  data () {
    const remoteOptions = this.getRemoteOptions();
    return {
      formData: this.dataSource,
      formItemList: this.formColumns,
      expandStatus: this.defaultExpandStatus,
      selectRemoteLoading: {},
      remoteOptions,
      setFieldsVisible: false,
      totalRowNum: 0
    };
  },
  mounted () {},
  computed: {
    ...mapGetters('permissions/systemBtns', ['showBtn']),
    /* 日期选择器title */
    dateTitle () {
      let target = this.formItemList.find((item) => {
        return item.type === 'datePicker';
      });
      if (!target) {
        return '';
      }
      if (!this.formData[target.prop]) {
        return '';
      }
      if (target.datePickerType === 'date') {
        return '';
      }
      return this.formData[target.prop].join(' - ');
    },
  },
  watch: {
    dataSource: {
      handler (newVal) {
        this.formData = newVal
      },
      immediate: true,
      deep: true
    },
    formColumns: {
      handler (val) {
        this.formItemList = val
        if (!this.defaultExpandStatus) {
          this.handlePackUp();
        }
      },
      deep: true,
      immediate: true
    },
    formItemList: {
      handler (val) {
        this.totalRowNum = Math.ceil(val.length / this.colNumOfRow)
      },
      deep: true,
      immediate: true
    }
  },
  methods: {
    getCategoryUuid (val) {
      this.formData.categoryCode = val;
    },
    // 按钮控制栏有额外插槽按钮内容
    hasSlotByExtensionAction () {
      return Object.keys(this.$slots).length !== 0;
    },
    // 获取查询按钮栏类名
    getClassNameBySearchBtnBar () {
      return this.hasSlotByExtensionAction() ? 'table-action' : '';
    },
    /* 获取表单数据 */
    getFormDataFunc () {
      return this.formData;
    },
    /* 查询表单数据 */
    handleQueryForm (actionBtnName) {
      /* 如果没有name，就默认是查询按钮 */
      const curBtnId = getBtnsId(actionBtnName || this.searchBtnName);
      sessionStorage.setItem('buttonId', curBtnId);
      this.$emit('getFormData', this.formData);
      /* 如果有外部传入的查询方法，就进行调用 */
      if (this.handleSearchForm) {
        this.handleSearchForm(this.formData);
      }
    },
    /* 清空表单数据 */
    handleResetForm () {
      this.$refs[this.refName].resetFields();
      /* 如果有外部传入的清空方法，就进行调用 */
      if (this.handleClearForm) {
        this.handleClearForm();
      }
      /* 如果开启清空同时查询功能，就调用查询事件方法 */
      if (this.isResetToQuery) {
        this.handleQueryForm();
      }
      if (this.$refs.categorySelect) {
        this.$refs.categorySelect.forEach(item => {
          item.clearCategoryNodes()
        })
      }
    },
    /* 收起表单事件 */
    handlePackUp () {
      this.expandStatus = false;
      this.formItemList = this.formColumns.reduce((value, item, index) => {
        if (index < this.colNumOfRow) {
          value.push(item);
        }
        return value;
      }, []);
    },
    /* 展开表单事件 */
    handleOpenUp () {
      this.expandStatus = true;
      this.formItemList = this.formColumns;
    },
    // 收起按钮
    packUpBtnFn () {
      return (<el-button
        type="text"
        icon="el-icon-arrow-up"
        onClick={() => { this.handlePackUp(); }}
      >收起筛选</el-button>);
    },
    // 展开按钮
    openUpBtnFn () {
      return (<el-button
        type="text"
        icon="el-icon-arrow-down"
        onClick={() => { this.handleOpenUp(); }}
      >展开筛选</el-button>);
    },
    // 查询按钮
    searchBtnFn () {
      return (<el-button
        type="primary"
        size="mini"
        onClick={() => { this.handleQueryForm(); }}
      >{this.searchBtnName}
      </el-button>);
    },
    // 清空按钮
    resetBtnFn () {
      // 如果有特殊渲染，返回特殊渲染的按钮
      if (this.resetBtnRender) {
        return this.resetBtnRender();
      }
      return (<el-button
        size="mini"
        onClick={() => { this.handleResetForm(); }}
      >{this.resetBtnName}
      </el-button>);
    },
    // 自定义筛选字段
    customSearchFieldsBtn () {
      return (<el-button
        size="mini"
        onClick={() => { this.showFieldsDialog(); }}
      >自定义筛选条件</el-button>);
    },
    actionRender (h) {
      const packUpBtn = this.packUpBtnFn();
      const openUpBtn = this.openUpBtnFn();
      const resetBtn = this.resetBtnFn();
      const searchBtn = this.searchBtnFn();
      let packOrOpenBtn = <div></div>;
      if (this.isScalingBtn) {
        packOrOpenBtn = this.expandStatus ? packUpBtn : openUpBtn;
      }
      return (
        <div class={this.getClassNameBySearchBtnBar()}>
          {packOrOpenBtn}
          {resetBtn}
          {searchBtn}
          {this.needSetSearchFields ? this.customSearchFieldsBtn() : null}
        </div>
      );
    },
    handleFilterOptions (query = '', obj) {
      let arr = obj.allOptions.filter(item => {
        return item.label.includes(query);
      });
      if (arr.length > 30) {
        obj.options = arr.slice(0, 30);
      } else {
        obj.options = arr;
      }
    },
    // 获取远程搜索下拉options
    getRemoteOptions () {
      const options = this.formColumns.reduce((value, item) => {
        if (item.type === 'select' && item.remote) {
          value[item.prop] = [];
        }
        return value
      }, {});
      return options;
    },
    // select下拉远程请求
    async handleRemoteSelect (val, item) {
      if (!val) {
        this.remoteOptions[item.prop] = [];
        return false;
      }
      const data = { [item.paramKey]: val, ...item.extraParams };
      const loadingFn = state => { this.selectRemoteLoading[item.prop] = state };
      const res = await item.remoteMethod(data, loadingFn);
      if (res?.data) {
        this.remoteOptions[item.prop] = res.data;
      }
    },
    // 获取select下拉options集合
    getSelectOptions (item) {
      const { remote, options, selectData, prop } = item;
      return remote ? this.remoteOptions[prop] : options || selectData;
    },
    // 获取下拉option相关属性key
    getSelectOptionKeys (option, item) {
      const defaultKeys = { valueKey: 'value', labelKey: 'label', optionKey: 'value' };
      const { valueKey, labelKey, optionKey, codeKey } = item?.optionKeys ?? defaultKeys;
      const options = {
        value: option[valueKey],
        label: codeKey? `${option[labelKey]}(${option[codeKey]})` : option[labelKey],
        key: option[optionKey]
      }
      return options;
    },
    // select下拉款单个option是否禁用方法
    isOptionDisabled (option, item) {
      if (!this.optionDisabledMethod) { return false; }
      return this.optionDisabledMethod({ option, item });
    },
    // 展示自定义筛选条件弹框
    showFieldsDialog () {
      this.setFieldsVisible = true;
    },
    // 自定筛选项提交回调
    setSearchFieldCallback () {
      // 刷新筛选条件
      this.$emit('getSearchFormFields')
    }
  }
};
</script>
<style lang="less" scoped>
/deep/ .el-range-input {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/deep/ .el-range-separator {
  display: flex;
  justify-content: center;
}
.table-action {
  margin-right: 10px;
}
</style>
